/*	
 * Popup related scripts.
 *	
 * @author Li Yang (young-lee@21cn.com)	
 */	

var HoverObserver = function(target, hoverDelay, overCB, overDelayCB, outCB) {
	target = $(target);
	if (!target.id) { alert("HoverObserver requires the target element has an ID!"); return; }
	
	this.target = target;
	this.hoverDelay = hoverDelay;
	this.overCB = overCB;
	this.overDelayCB = overDelayCB;
	this.outCB = outCB;
};

HoverObserver.prototype = {
	start: function() {
		if (this.target._hoverObserver == this) return; // I'm already started
		if (this.target._hoverObserver) { alert("Only one HoverObserver on an element allowed!"); return; }
		this.target._hoverObserver = this;
		
		this.overObs = this.over.bind(this);
		this.outObs = this.out.bind(this);
		Event.observe(this.target, "mouseover", this.overObs);
		Event.observe(this.target, "mouseout", this.outObs);
		this.overTimeout = 0;
		this.outTimeout = 0;
	},
	
	over: function() {
		if (this.overCB) this.overCB(this.target);

		if (this.overTimeout == 0 && this.overDelayCB)
			this.overTimeout = window.setTimeout("$('"+this.target.id+"')._hoverObserver.overDelayCB($('"+this.target.id+"'));", this.hoverDelay);

		if (this.outTimeout > 0) window.clearTimeout(this.outTimeout);
		this.outTimeout = 0;
	},
	
	out: function() {
		if (this.overTimeout > 0) window.clearTimeout(this.overTimeout);
		this.overTimeout = 0;
		
		if (this.outTimeout == 0 && this.outCB)
			this.outTimeout = window.setTimeout("$('"+this.target.id+"')._hoverObserver.outCB($('"+this.target.id+"'));", this.hoverDelay);
	},
	
	stop: function() {
		if (this.target._hoverObserver != this) return; // I'm not observing
		Event.stopObserving(this.target, "mouseover", this.overObs);
		Event.stopObserving(this.target, "mouseout", this.outObs);
		this.overObs = null;
		this.outObs = null;
		if (this.overTimeout > 0) window.clearTimeout(this.overTimeout);
		if (this.outTimeout > 0) window.clearTimeout(this.outTimeout);
		this.target._hoverObserver = null;
	}
};

var Ypop = {
	enhance: function(a) {
		var popup = $(a.rel);
		if (!popup) { alert("popup content should be identified by attribute 'rel'"); return; }
		if (!a.id) a.id = a.rel + "_a";
		if (!a.href) a.href = "javascript:;";

		// external interface
		popup.a = a;
		a.popActive = false;
		a.pop = function() { Ypop.activate(a); };
		a.popHide = function() { Ypop.deactivate(a); };

		a.popHob = new HoverObserver(a, 500, null, a.pop, null);
		a.hideHob = new HoverObserver(a, 500, Ypop._over, null, Ypop._out);
		a.hideHob2 = new HoverObserver(popup, 500, Ypop._over, null, Ypop._out);

		if ("false"!=a.getAttribute("poponclick")) Event.observe(a, "click", a.pop);
		if ("false"!=a.getAttribute("poponhover")) a.popHob.start();
	},
	
	deenhance: function(a) {
		if (a.popActive) Ypop.deactivate(a);
		Event.stopObserving(a, "click", a.pop);
		a.popHob.stop();
		a.hideHob.stop();
		a.hideHob2.stop();
		a.pop = a.popHide = a.popHob = a.hideHob = a.hideHob2 = null;
	},
	
	activate: function(a) {
		Event.stopObserving(a, "click", a.pop);
		a.popHob.stop();

		var popup = $(a.rel);
		popup.style.marginTop = "0"; // shows the popup
		a.popActive = true;
		a.isHover = false;
		popup.isHover = false;
		
		if ("true"==a.getAttribute("popattop")) {
			// move the popup to the top of DOM tree
			if (!popup.origPos)
				popup.origPos = Yutil.abspos(popup);
			popup.origSibling = popup.nextSibling;
			document.body.appendChild(popup);
			popup.style.position = "absolute";
			Yutil.moveTo(popup, popup.origPos[0], popup.origPos[1]);
		}
		
		a.hideHob.start();
		a.hideHob2.start();

		// notify event
		if (popup.onPopup)
			popup.onPopup();

	},
	
	_over: function(aOrP) {
		aOrP.isHover = true;
	},
	
	_out: function(aOrP) {
		aOrP.isHover = false;
		var a = aOrP.a || aOrP;
		var popup = $(a.rel);
		if (a.isHover == false && popup.isHover == false && (!$('htmlbody_loadingMessage1000') || $('htmlbody_loadingMessage1000').style.display=='none')) {
			Ypop.deactivate(a);
		}
	},
	
	deactivate: function(a) {
		a.hideHob.stop();
		a.hideHob2.stop();

		var popup = $(a.rel);
		popup.style.marginTop = "-99999em"; // hides the popup
		a.popActive = false;

		if ("true"==a.getAttribute("popattop")) {
			// move back the popup
			popup.origSibling.parentNode.insertBefore(popup, popup.origSibling);
		}

		if ("false"!=a.getAttribute("poponclick")) Event.observe(a, "click", a.pop);
		if ("false"!=a.getAttribute("poponhover")) a.popHob.start();
	}
};

// register enhancement
Yutil.en.register("a.pop", Ypop.enhance, Ypop.deenhance);
